/*
*    Qizx/open 3.0 beta
*
* This code is the open-source version of Qizx.
* Copyright (C) 2004-2009 Axyana Software -- All rights reserved.
*
* The contents of this file are subject to the Mozilla Public License 
*  Version 1.1 (the "License"); you may not use this file except in 
*  compliance with the License. You may obtain a copy of the License at
*  http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
*  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
*  for the specific language governing rights and limitations under the
*  License.
*
* The Initial Developer of the Original Code is Xavier Franc - Axyana Software.
*
*/
using System;
using EvaluationException = System.Qizx.Api.EvaluationException;
using XQItem = System.Qizx.XQuery.XQItem;
using XQItemType = System.Qizx.XQuery.XQItemType;
using XQType = System.Qizx.XQuery.XQType;
using XQValue = System.Qizx.XQuery.XQValue;
namespace System.Qizx.XQuery.Dt
{
	
	/// <summary> A sequence that stores Integer items in an array.</summary>
	public class IntegerArraySequence:GenericValue
	{
		protected internal long[] items;
		
		protected internal int size;
		
		protected internal int index = - 1;
		
		public IntegerArraySequence(long[] items, int size, XQItemType itemType)
		{
			init(items, size);
			this.itemType = itemType;
		}
		
		public IntegerArraySequence(long[] items, int size):this(items, size, XQType.INTEGER)
		{
		}
		
		public IntegerArraySequence(int[] items, int size)
		{
			long[] ritems = new long[size];
			for (int i = size; --i >= 0; )
				ritems[i] = items[i];
			init(ritems, size);
			itemType = XQType.INT;
		}
		
		public IntegerArraySequence(short[] items, int size)
		{
			long[] ritems = new long[size];
			for (int i = size; --i >= 0; )
				ritems[i] = items[i];
			init(ritems, size);
			itemType = XQType.SHORT;
		}
		
		public IntegerArraySequence(sbyte[] items, int size)
		{
			long[] ritems = new long[size];
			for (int i = size; --i >= 0; )
				ritems[i] = items[i];
			init(ritems, size);
			itemType = XQType.BYTE;
		}
		
		public IntegerArraySequence(char[] items, int size)
		{
			long[] ritems = new long[size];
			for (int i = size; --i >= 0; )
				ritems[i] = items[i];
			init(ritems, size);
		}
		
		private void  init(long[] items, int size)
		{
			this.items = items;
			this.size = size;
			itemType = XQType.INTEGER;
		}
		
		public override bool Next()
		{
			if (++index >= size)
				return false;
			item = new SingleInteger(items[index], itemType); // Hmmm
			return true;
		}
		
		public override XQItem QuickIndex(long index)
		{
			return index <= 0 || index > size?null:new SingleInteger(items[(int) index - 1], itemType);
		}
		
		public override XQValue BornAgain()
		{
			return new IntegerArraySequence(items, size, itemType);
		}
		
		internal static long[] unroll(XQValue value_Renamed)
		{
			long[] items = new long[8];
			int ptr = 1; // items[0] stores the length
			for (; value_Renamed.Next(); )
			{
				if (ptr >= items.Length)
				{
					long[] old = items;
					items = new long[old.Length * 2];
					Array.Copy(old, 0, items, 0, old.Length);
				}
				items[ptr++] = value_Renamed.ValueAsInteger;
			}
			items[0] = ptr - 1;
			return items;
		}
		
		/// <summary> Converts a Value representing a sequence of integers into an integer
		/// array.
		/// </summary>
		public static long[] expandIntegers(XQValue value_Renamed)
		{
			long[] items = unroll(value_Renamed);
			int len = (int) items[0];
			long[] ritems = new long[len];
			Array.Copy(items, 1, ritems, 0, len);
			return ritems;
		}
		
		/// <summary> Converts a Value representing a sequence of ints into an int array.</summary>
		public static int[] expandInts(XQValue value_Renamed)
		{
			long[] items = unroll(value_Renamed);
			int len = (int) items[0];
			int[] ritems = new int[len];
			for (int i = 0; i < len; i++)
				ritems[i] = (int) items[i + 1];
			return ritems;
		}
		
		/// <summary> Converts a Value representing a sequence of shorts into an short array.</summary>
		public static short[] expandShorts(XQValue value_Renamed)
		{
			long[] items = unroll(value_Renamed);
			int len = (int) items[0];
			short[] ritems = new short[len];
			for (int i = 0; i < len; i++)
				ritems[i] = (short) items[i + 1];
			return ritems;
		}
		
		/// <summary> Converts a Value representing a sequence of bytes into an byte array.</summary>
		public static sbyte[] expandBytes(XQValue value_Renamed)
		{
			long[] items = unroll(value_Renamed);
			int len = (int) items[0];
			sbyte[] ritems = new sbyte[len];
			for (int i = 0; i < len; i++)
				ritems[i] = (sbyte) items[i + 1];
			return ritems;
		}
		
		/// <summary> Converts a Value representing a sequence of chars into an char array.</summary>
		public static char[] expandChars(XQValue value_Renamed)
		{
			long[] items = unroll(value_Renamed);
			int len = (int) items[0];
			char[] ritems = new char[len];
			for (int i = 0; i < len; i++)
				ritems[i] = (char) items[i + 1];
			return ritems;
		}
	}
}